<template>
	<Form :label-width="90" label-position="right" style="margin-top:12px">
		<FormItem label="故障位置">
			<Cascader :data="floorTree" @on-change="focusToRoom" clearable placeholder="报修房间"
				v-model="info.space" />
		</FormItem>
		<FormItem label="故障设备">
			<Cascader :data="deviceTree" :load-data="loadDevice" clearable placeholder="报修设备"
				v-model='info.device' />
		</FormItem>
		<FormItem label="处理班组">
			<Select clearable v-model="info.template">
				<Option :key="i.value" :value="i.value" v-for="i in templateArray">{{i.text}}</Option>
			</Select>
		</FormItem>
		<FormItem label="截止日期">
			<DatePicker :options="option" v-model="info.deadline" />
		</FormItem>
		<FormItem label="优先级">
			<Select v-model="info.priority">
				<Option :value="0">特急</Option>
				<Option :value="1">紧急</Option>
				<Option :value="2">普通</Option>
			</Select>
		</FormItem>
		<FormItem label="问题描述">
			<AutoComplete :data="resolve" :transfer=false @on-search="searchDescribe" v-model="info.describe" />
		</FormItem>
		<FormItem label="原因分析">
			<AutoComplete :data="reason" :transfer=false @on-change="setAdvice" v-model="info.why" />
		</FormItem>
		<FormItem label="解决建议">
			<AutoComplete :data="advice" :transfer=false v-model="info.how" />
		</FormItem>
		<FormItem label="添加附件">
			<Upload :max-size=10240 :on-exceeded-size="handleExceeded" :on-preview='previewFile'
				action="/file/upload/" multiple ref="upload" with-credentials>
				<Button ghost>上传</Button>
			</Upload>
		</FormItem>
		<FormItem label="">
			<div style="text-align: right">
				<Button :key="i.text" :loading="loading" @click="submit" ghost style="margin-left: 6px"
					v-for='i in buttons'>{{i.text}}
				</Button>
				<Button :loading=loading @click="close" class=default ghost style="margin-left: 6px">关闭</Button>
				<Button :loading="loading" @click="$router.go(-1)" ghost style="margin-left: 6px">返回</Button>
			</div>
		</FormItem>
	</Form>
</template>
<script lang="ts">
	import { Component, Prop, Vue } from "vue-property-decorator";
	import {
		AutoComplete,
		Button,
		Cascader,
		DatePicker,
		Form,
		FormItem,
		Modal,
		Option,
		Select,
		Upload
	} from "view-design";
	import request from "@/request";
	import { Route } from "vue-router";
	import moment from "moment";
	import qs from "qs";
	import { CreateElement, VNode } from "vue";

	interface Tree {
		label:string,
		value:number,
		type:"system" | "category" | "device",
		loading?:boolean,
		children?:Tree[]
	}

	interface resolve {
		what:string,
		how:string,
		why:string
	}

	@Component({
		components: {
			AutoComplete,
			Button,
			Cascader,
			DatePicker,
			Form,
			FormItem,
			Modal,
			Option,
			Select,
			Upload
		}
	})
	export default class Distribution extends Vue {
		@Prop(Array) readonly errorSpace?:number[];
		@Prop(Array) readonly device?:number[];
		@Prop(Date) readonly deadline?:Date;
		@Prop(Number) readonly priority?:number;
		@Prop({ type: Array, default: () => ([]) }) readonly templateArray?:{ text:string, value:number }[];
		@Prop(Number) readonly template?:Number;
		@Prop(String) readonly description?:string;
		@Prop({ type: Array, default: () => ([]) }) readonly btnList?:{ value:("" | number), text:string }[];
		floorTree:Tree[] = [];
		deviceTree:Tree[] = [];
		resolve:string[] = [];
		reason:string[] = [];
		advice:string[] = [];
		info = {
			space: this.errorSpace,
			device: this.device,
			deadline: this.deadline,
			priority: this.priority,
			describe: this.description,
			fileList: [],
			template: this.template,
			how: "",
			why: ""
		};
		loading:boolean = false;
		readonly option = {
			disabledDate (date:Date):boolean {
				return date && date.valueOf() < Date.now();
			}
		};
		private resolveSource:resolve[] = [];
		private readonly listener = this.$store.subscribe(mutation => {
			if (mutation.type === "findRoom" && mutation.payload.path) {
				this.info.space = mutation.payload.path;
			}
		});

		get buttons ():{ value:number | "", text:string }[] {
			let list = this.btnList || [];
			if (list.length > 0) {
				return list;
			} else {
				list.push({ value: "", text: "确认" });
				return list;
			}
		}

		loadDevice (item:Tree, callback:Function) {
			item.loading = true;
			let url:string;
			let params;
			if (item.type === "system") {
				url = "/device/devicecategory/";
				params = {
					DeviceType__mepsystemtype: item.value,
					DeviceType__Device__room__floor: this.$store.state.floorValue,
					DeviceType__Device__room: this.info.space ? this.info.space[ 2 ] : ""
				};
			} else {
				url = "/device/device2/";
				params = {
					devicetype__device_category: item.value,
					room: this.info.space ? this.info.space[ 2 ] : "",
					room__floor: this.$store.state.floorValue
				};
			}
			request({
				url,
				params
			}).then(({ data }) => {
				if (url === "/device/devicecategory/") {
					item.children = data.map((t:any):Tree => ({
						label: t.name,
						value: t.id,
						loading: false,
						type: "category",
						children: []
					}));
				} else {
					item.children = data.results.map((t:any):Tree => ({
						label: t.device_category_name + t.code,
						value: t.id,
						type: "device"
					}));
				}
				item.loading = false;
				callback();
			});
		}

		getCurrentDeviceTree () {
			request({
				url: "/device/mepsystemtype/",
				params: {
					DeviceType__Device__room: this.info.space ? this.info.space[ 2 ] : ""
				}
			}).then(({ data }) => {
				this.deviceTree = data.map((t:any) => ({
					label: t.name,
					value: t.id,
					type: "system",
					loading: false,
					children: []
				}));
			});
		}

		searchDescribe (text:string) {
			if (text === "") {
				this.resolve = [];
			} else {
				let regexp:RegExp = new RegExp(text);
				let set:Set<string> = new Set();
				let set2:Set<string> = new Set();
				let set3:Set<string> = new Set();
				this.resolveSource.forEach(t => {
					if (regexp.test(t.what)) {
						set.add(t.what);
						set2.add(t.why);
						set3.add(t.how);
					}
				});
				if (set.size === 0) {
					set.add("没有相关建议");
				}
				this.resolve = Array.from(set);
				this.reason = Array.from(set2);
				this.advice = Array.from(set3);
			}
		}

		focusToRoom (value:number[]) {
			if (value && value.length === 3) {
				request(`/space/room/${ value[ 2 ] }/`).then(({ data }) => {
					this.$store.commit("findRoom", { id: data.room_guid, floor: value[ 1 ] });
				});
			}
			this.getCurrentDeviceTree();
		}

		previewFile (file:any) {
			let url = file.response.data.fileurl;
			if (!file.response.data.image) {
				window.open(url);
			} else {
				const config = {
					render (h:CreateElement):VNode {
						return h("img", { attrs: { src: url }, staticStyle: { width: "100%" } });
					},
					width: 800
				};
				// @ts-ignore
				Modal.info(config);
			}
		}

		handleExceeded () {
			this.$Notice.error({ desc: "文件大小超出限制" });
		}

		setAdvice (value:string) {
			const temp = this.resolveSource.find(t => t.why === value);
			if (temp) {
				this.info.how = temp.how;
			}
		}

		close () {
			this.$Modal.confirm({
				content: "确认要关闭工单吗?",
				onOk: () => {
					this.loading = true;
					request({
						url: `/repair/rest/projectevent/${ this.$route.params.id }/`,
						data: {
							status: 4
						},
						method: "PATCH"
					}).then(() => {
						this.$router.go(-1);
					});
				}
			});
		}

		submit () {
			this.loading = true;
			const deviceLength = this.info.device ? (this.info.device.length - 1) : -1;
			let data = {
				opt: "dealevent",
				describe: this.info.why || "" + this.info.how,
				eid: this.$route.params.id,
				oid: "",
				originDescribe: this.info.describe,
				[ [ "mepsystemtype", "devicetype", "device" ][ deviceLength ] ]: this.info.device ? this.info.device[ deviceLength ] : "",
				deadline: this.info.deadline ? moment(this.info.deadline).format("YYYY-MM-DD") : "",
				priority: this.info.priority,
				template: this.info.template,
				space: this.info.space,
				how: this.info.how,
				fileids: (this.$refs.upload as any).fileList.map((t:any) => t.response.data.docId)
			};
			request({
				url: "/repair/eventopt/",
				method: "post",
				data,
				transformRequest: [ function (data) {
					return qs.stringify(data, { encode: false, arrayFormat: "brackets" });
				} ]
			}).then(() => {
				this.$router.go(-1);
			});
		}

		mounted () {
			request("/prj/facilityfloorrooms/").then(({ data }) => {
				this.floorTree = [ data.data[ 0 ] ];
			});
			request("/repair/rest/requirement/").then(({ data }) => {
				this.resolveSource = data;
			});
			this.getCurrentDeviceTree();
			this.description && this.searchDescribe(this.description);
		}

		beforeRouteLeave (to:Route, from:Route, next:Function) {
			this.listener();
			next();
		}
	}

</script>
